/* SwitchView.m
 * Written By:  Thomas Burkholder
 *
 * You may freely copy, distribute, and reuse the code in this example.
 * NeXT disclaims any warranty of any kind, expressed or  implied, as to its
 * fitness for any particular use.
 */

// name space protected for WavesWorld by the addition of the "WWTT" prefix


#import "WWTTSwitchView.h"
#import <apps/InterfaceBuilder.h>

@implementation WWTTSwitchView

+ initialize { return [WWTTSwitchView setVersion:2], self; }

- initFrame:(const NXRect *)frameRect
{
	[super initFrame:frameRect];
	[self setTitle:"WWTTSwitchView"];
	views = [[List alloc] init];
	valueSelector = (SEL)0;
	initialViewNumber = 0;
	currentViewNumber = -1;
	return self;
}

- free
{
	[views free];
	return [super free];
}

- awakeFromNib
{
	[self setViewNumber:initialViewNumber];
	return self;
}

- setViewNumber:(int)ndx
{
	id old, v = [views objectAt:ndx];

	if (!v) return self;
	old = [self setContentView:v];
	if (NX_NOT_IN_LIST == [views indexOf:old]) {
		[old free];
	}
	currentViewNumber = ndx;
	return self;
}

- views
{
	return views;
}

- takeViewNumberFrom:sender
{
	int i;
	SEL vs;

	if (!valueSelector && sender)
		vs = [self guessValueSelectorForSwitchSource:sender];
	else
		vs = valueSelector;

	i = (int)[sender perform:vs];
	[self setViewNumber:i];
	[self display];
	return self;
}

- takeTagFrom:sender
{
	int i;


        // wave stuck me in cause this makes more sense...
        if ([sender respondsTo:@selector(selectedCell)])  /* it's a Matrix */
        {  i = [[sender selectedCell] tag];
        }
        else
        {  i = [sender tag];
        }
	[self setViewNumber:i];
	[self display];
	return self;
}

- takeIntValueFrom:sender
{
	[self setViewNumber:[sender intValue]];
	[self display];
	return self;
}

- takeSelectedRowFrom:sender
{
	[self setViewNumber:[sender selectedRow]];
	[self display];
	return self;
}

- takeSelectedColFrom:sender
{
	[self setViewNumber:[sender selectedCol]];
	[self display];
	return self;
}


- setValueSelector:(SEL)aSelector
{
	valueSelector = aSelector;
	return self;
}

- (SEL)valueSelector
{
	return valueSelector;
}

- setInitialViewNumber:(int)num
{
	initialViewNumber = num;
	return self;
}

- (int)initialViewNumber
{
	return initialViewNumber;
}

- (SEL)guessValueSelectorForSwitchSource:sender
{
	if ([sender isKindOf:[Matrix class]]) { int r, c;
		[sender getNumRows:&r numCols:&c];
		if (r >= c)
			return @selector(selectedRow);
		else
			return @selector(selectedCol);
	} else if ([sender respondsTo:@selector(isEditable)] &&
			([sender isEditable]) &&
			([sender respondsTo:@selector(intValue)])) {
		return @selector(intValue);
	} else if ([sender isKindOf:[Button class]] ||
						[sender isKindOf:[ButtonCell class]]) {
		return @selector(tag);
	} else if ([sender respondsTo:@selector(intValue)]) {
		return @selector(intValue);
	} else if ([sender respondsTo:@selector(tag)]) {
		return @selector(tag);
	}
	return (SEL)0;
}

- drawSelf:(const NXRect *)rects :(int)rectCount
{
	// Problem with IB not calling awakeFromNib
	if (currentViewNumber == -1 && [views count] > 0) {
		[self setViewNumber:initialViewNumber];
	}
	return [super drawSelf:rects :rectCount];
}

- read:(NXTypedStream *)stream
{
  int  version;


  [super read:stream];

  version = NXTypedStreamClassVersion(stream,"WWTTSwitchView");
  if (version == 0)
  {  NXReadType(stream,":",&valueSelector);
     views = NXReadObject(stream);
     currentViewNumber = -1;
  }
  if (version == 1)
  {  NXReadType(stream,":",&valueSelector);
     views = NXReadObject(stream);
     NXReadType(stream,"i",&initialViewNumber);
     currentViewNumber = -1;
  }
  if (version == 2)
  {  NXReadType(stream,":",&valueSelector);
     views = NXReadObject(stream);
     NXReadType(stream,"i",&initialViewNumber);
     NXReadType(stream,"i",&currentViewNumber);
  }

  return self;
}

- write:(NXTypedStream *)stream
{
    [super write:stream];
    NXWriteType(stream,":",&valueSelector);
    NXWriteObject(stream,views);
    NXWriteType(stream,"i",&initialViewNumber);
    NXWriteType(stream,"i",&currentViewNumber);
    return self;
}
@end
